package es.ucm.fdi.healthpred.vista;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.List;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

import org.eclipse.wb.swing.FocusTraversalOnArray;

import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;
import com.jgoodies.forms.layout.Sizes;

import es.ucm.fdi.healthpred.controlador.Controlador;
import es.ucm.fdi.healthpred.controlador.excepciones.ExcepcionTransaccion;
import es.ucm.fdi.healthpred.controlador.utils.ConstantsString;
import es.ucm.fdi.healthpred.controlador.utils.StringsHP_BD;
import es.ucm.fdi.healthpred.modelo.beans.Persona;

/**
 * Formulario principal de la aplicaci&oacute;n.
 * 
 * @since 1.0
 * 
 * @version 1.0
 * 
 * @author &Aacute;lvaro G&oacute;mez Porris
 * @author V&iacute;ctor L&oacute;pez Monte
 * @author Carlos Rodr&iacute;guez Colliga
 * 
 */
public class FormPrincipal extends JFrame {

	public static final ImageIcon iconoAviso = new ImageIcon(
			FormPrincipal.class.getClassLoader()
					.getResource("logo_100x100.png"));

	public static final int MIN_FILAS_TABLA = 15;
	private static final int alto = 660;
	private static final int ancho = 1020;
	/*
	 * Charset ISO-8859-1 (Tildes y enyes):
	 * 
	 * a = \u00e1; A = \u00c1; e = \u00e9; E = \u00c9; i = \u00ed; I = \u00cd;
	 * 
	 * o = \u00f3; O = \u00d3; u = \u00fa; U = \u00da;
	 * 
	 * enye = \u00f1; Enye = \u00d1;
	 */
	private static final long serialVersionUID = 1L;

	private JButton btnAyuda = new JButton("Ayuda");
	private JButton btnBuscar = new JButton("Buscar cliente");
	private JButton btnConsultar = new JButton("Consultar");
	private JButton btnEditar = new JButton("Editar cliente");
	private JButton btnEliminar = new JButton("Eliminar cliente");
	private JButton btnNuevo = new JButton("Nuevo cliente");
	private JButton btnTodos = new JButton("Ver todos");
	private JButton btnVer = new JButton("Ver cliente");
	private HashMap<String, Object> busquedaHM;
	private ModoBuscar modoBuscar = ModoBuscar.M_Y;
	private JPanel panelCentral = new JPanel();
	private JPopupMenu popupAyuda = new JPopupMenu();
	private JPopupMenu popupMenu = new JPopupMenu();
	private JRadioButton rdbtnO = new JRadioButton("O");
	private JRadioButton rdbtnY = new JRadioButton("Y");
	private JScrollPane scrollPane = new JScrollPane();
	private JTable tabla;
	private JTextFieldFoco textFieldApellido;
	private JTextFieldFoco textFieldDni;
	private JTextFieldFoco textFieldNombre;
	private JTextFieldFoco textFieldTelefono;
	private JToolBar toolBar = new JToolBar();

	/**
	 * Constructora de la ventana principal.
	 */
	public FormPrincipal() {
		init();
	}

	/**
	 * Actualiza la tabla en funci&o;n de la lista de entrada y de si va
	 * precedido de una b&uacute;squeda o no.
	 */
	public void actualizaTabla(List<Object> listaPersonas, boolean busqueda) {
		Persona persona;
		DefaultTableModel modelo = (DefaultTableModel) tabla.getModel();
		int filasAntes = modelo.getRowCount();
		int total = 0;

		textFieldDni.setText("");
		textFieldNombre.setText("");
		textFieldApellido.setText("");
		textFieldTelefono.setText("");

		if (listaPersonas != null) {
			total = listaPersonas.size();
		}

		if ((total > 0) || ((total == 0) && (!busqueda))) {
			for (int i = 0; i < filasAntes; i++) {
				modelo.removeRow(0);
			}
		}

		if (total > 0) {
			if (busqueda) {
				btnTodos.setEnabled(true);
			}

			for (int i = 0; i < total; i++) {
				persona = (Persona) listaPersonas.get(i);
				modelo.addRow(new String[] { persona.getDni(),
						persona.getNombre(), persona.getApellido1(),
						persona.getApellido2(),
						persona.getTelefono().toString(),
						StringsHP_BD.fechaHP(persona.getFechaNacimiento()),
						persona.getLocalidad(),
						StringsHP_BD.provinciaHP(persona.getProvincia()) });
			}
		}

		if (total < MIN_FILAS_TABLA) {
			for (int i = 0; i < (MIN_FILAS_TABLA - total); i++) {
				modelo.addRow(new String[] { null, null, null, null, null,
						null, null, null, null });
			}
		}
		repaint();
	}

	/**
	 * @return the btnAyuda
	 */
	public JButton getBtnAyuda() {
		return btnAyuda;
	}

	/**
	 * @return the btnBuscar
	 */
	public JButton getBtnBuscar() {
		return btnBuscar;
	}

	/**
	 * @return the btnConsultar
	 */
	public JButton getBtnConsultar() {
		return btnConsultar;
	}

	/**
	 * @return the btnEditar
	 */
	public JButton getBtnEditar() {
		return btnEditar;
	}

	/**
	 * @return the btnEliminar
	 */
	public JButton getBtnEliminar() {
		return btnEliminar;
	}

	/**
	 * @return the btnNuevo
	 */
	public JButton getBtnNuevo() {
		return btnNuevo;
	}

	/**
	 * @return the btnVer
	 */
	public JButton getBtnVer() {
		return btnVer;
	}

	/**
	 * @return the modoBuscar
	 */
	public ModoBuscar getModoBuscar() {
		return modoBuscar;
	}

	/**
	 * @return the panelCentral
	 */
	public JPanel getPanelCentral() {
		return panelCentral;
	}

	/**
	 * @return the popupMenu
	 */
	public JPopupMenu getPopupMenu() {
		return popupMenu;
	}

	/**
	 * @return the rdbtnO
	 */
	public JRadioButton getRdbtnO() {
		return rdbtnO;
	}

	/**
	 * @return the rdbtnY
	 */
	public JRadioButton getRdbtnY() {
		return rdbtnY;
	}

	/**
	 * @return the scrollPane
	 */
	public JScrollPane getScrollPane() {
		return scrollPane;
	}

	/**
	 * @return La tabla
	 */
	public JTable getTabla() {
		return tabla;
	}

	/**
	 * @return
	 */
	public JTextFieldFoco getTextFieldApellido() {
		return textFieldApellido;
	}

	/**
	 * @return
	 */
	public JTextFieldFoco getTextFieldDni() {
		return textFieldDni;
	}

	/**
	 * @return
	 */
	public JTextFieldFoco getTextFieldNombre() {
		return textFieldNombre;
	}

	/**
	 * @return
	 */
	public JTextFieldFoco getTextFieldTelefono() {
		return textFieldTelefono;
	}

	/**
	 * @return La barra de botones
	 * @see JToolBar
	 */
	public JToolBar getToolBar() {
		return toolBar;
	}

	/**
	 * @param btnAyuda
	 *            the btnAyuda to set
	 */
	public void setBtnAyuda(JButton btnAyuda) {
		this.btnAyuda = btnAyuda;
	}

	/**
	 * @param btnBuscar
	 *            the btnBuscar to set
	 */
	public void setBtnBuscar(JButton btnBuscar) {
		this.btnBuscar = btnBuscar;
	}

	/**
	 * @param btnConsultar
	 *            the btnConsultar to set
	 */
	public void setBtnConsultar(JButton btnConsultar) {
		this.btnConsultar = btnConsultar;
	}

	/**
	 * @param btnEditar
	 *            the btnEditar to set
	 */
	public void setBtnEditar(JButton btnEditar) {
		this.btnEditar = btnEditar;
	}

	/**
	 * @param btnEliminar
	 *            the btnEliminar to set
	 */
	public void setBtnEliminar(JButton btnEliminar) {
		this.btnEliminar = btnEliminar;
	}

	/**
	 * @param btnNuevo
	 *            the btnNuevo to set
	 */
	public void setBtnNuevo(JButton btnNuevo) {
		this.btnNuevo = btnNuevo;
	}

	/**
	 * @param btnVer
	 *            the btnVer to set
	 */
	public void setBtnVer(JButton btnVer) {
		this.btnVer = btnVer;
	}

	/**
	 * @param modoBuscar
	 *            the modoBuscar to set
	 */
	public void setModoBuscar(ModoBuscar modoBuscar) {
		this.modoBuscar = modoBuscar;
	}

	/**
	 * @param panelCentral
	 *            the panelCentral to set
	 */
	public void setPanelCentral(JPanel panelCentral) {
		this.panelCentral = panelCentral;
	}

	/**
	 * @param popupMenu
	 *            the popupMenu to set
	 */
	public void setPopupMenu(JPopupMenu popupMenu) {
		this.popupMenu = popupMenu;
	}

	/**
	 * @param rdbtnO
	 *            the rdbtnO to set
	 */
	public void setRdbtnO(JRadioButton rdbtnO) {
		this.rdbtnO = rdbtnO;
	}

	/**
	 * @param rdbtnY
	 *            the rdbtnY to set
	 */
	public void setRdbtnY(JRadioButton rdbtnY) {
		this.rdbtnY = rdbtnY;
	}

	/**
	 * @param scrollPane
	 *            the scrollPane to set
	 */
	public void setScrollPane(JScrollPane scrollPane) {
		this.scrollPane = scrollPane;
	}

	/**
	 * @param tabla
	 */
	public void setTabla(JTable tabla) {
		this.tabla = tabla;
	}

	/**
	 * @param textFieldApellido
	 */
	public void setTextFieldApellido(JTextFieldFoco textFieldApellido) {
		this.textFieldApellido = textFieldApellido;
	}

	/**
	 * @param textFieldDni
	 */
	public void setTextFieldDni(JTextFieldFoco textFieldDni) {
		this.textFieldDni = textFieldDni;
	}

	/**
	 * @param textFieldNombre
	 */
	public void setTextFieldNombre(JTextFieldFoco textFieldNombre) {
		this.textFieldNombre = textFieldNombre;
	}

	/**
	 * @param textFieldTelefono
	 */
	public void setTextFieldTelefono(JTextFieldFoco textFieldTelefono) {
		this.textFieldTelefono = textFieldTelefono;
	}

	/**
	 * @param toolBar
	 *            La nueva barra de botones.
	 * @see JToolBar
	 */
	public void setToolBar(JToolBar toolBar) {
		this.toolBar = toolBar;
	}

	/**
	 * Muestra una ventana de informaci&oacute;n.
	 * 
	 * @param msg
	 * @param titulo
	 */
	public void ventanaInfo(String msg, String titulo) {
		JOptionPane.showMessageDialog(this, msg, titulo,
				JOptionPane.INFORMATION_MESSAGE, FormPrincipal.iconoAviso);
	}

	/**
	 * Muestra una ventana que da a elegir entre dos opciones (S&iacute; o No).
	 * 
	 * @param msg
	 * @param titulo
	 * 
	 * @return El valor de la opci&oacute;n elegida.
	 */
	public int ventanaOpcion(String msg, String titulo) {
		return JOptionPane.showConfirmDialog(this, msg, titulo,
				JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
				iconoAviso);
	}

	/* PRIVADOS */
	private void actualizaSeleccion(int fila) {
		tabla.getSelectionModel().setSelectionInterval(fila - 1, fila - 1);
	}

	private void botonDerechoTablaActionPerformed(MouseEvent e) {
		if (tabla.getSelectedRow() != -1) {
			if (tabla.getValueAt(tabla.getSelectedRow(), 0) != null) {
				popupMenu.show(e.getComponent(), e.getX(), e.getY());
			}
		}
	}

	private void btnAyudaActionPerformed(ActionEvent e) {
		MouseEvent eventoMouse = new MouseEvent(((Component) e.getSource()), 0,
				e.getWhen(), KeyEvent.VK_UNDEFINED, 0, getContentPane().getY()
						+ ((Component) e.getSource()).getY(), 1, true);
		popupAyuda.show(eventoMouse.getComponent(), eventoMouse.getX(),
				eventoMouse.getY());
	}

	private void btnBuscarActionPerformed() {
		buscar();
	}

	private void btnConsultarActionPerformed() throws ExcepcionTransaccion {
		consultar();
	}

	private void btnEditarActionPerformed() {
		editar();
	}

	private void btnEliminarActionPerformed() {
		eliminar();
	}

	private void btnNuevoActionPerformed() {
		Controlador.showVistaSecundaria(ModoFormSecundario.M_NUEVO);
	}

	private void btnTodosActionPerformed() {
		Controlador.muestraTodosClientes();
		btnTodos.setEnabled(false);
	}

	private void btnVerActionPerformed() {
		ver();
	}

	private void buscar() {
		busquedaHM = new HashMap<String, Object>();
		busquedaHM.put(ConstantsString.B_DNI, getTextFieldDni().getText());
		busquedaHM
				.put(ConstantsString.B_NOMBRE, getTextFieldNombre().getText());
		busquedaHM.put(ConstantsString.B_APELLIDO, getTextFieldApellido()
				.getText());
		if (getTextFieldTelefono().getText().equals(ConstantsString.VACIO))
			busquedaHM.put(ConstantsString.B_TELEFONO, ConstantsString.VACIO);
		else
			busquedaHM.put(ConstantsString.B_TELEFONO,
					Integer.valueOf(getTextFieldTelefono().getText()));
		busquedaHM.put(ConstantsString.B_MODO, getModoBuscar());
		Controlador.buscar(busquedaHM);
	}

	private void consultar() {
		if (seleccionaCliente()) {
			Controlador.consultar(0);
			Controlador.consultar(1);
			Controlador.showVistaSecundaria(ModoFormSecundario.M_CONSULTAR);
		}
	}

	private void dobleClickTablaActionPerformed() {
		ver();
	}

	private void editar() {
		if (seleccionaCliente()) {
			Controlador.showVistaSecundaria(ModoFormSecundario.M_EDITAR);
		}
	}

	private void eliminar() {
		if (seleccionaCliente()) {
			Controlador.eliminarCliente();
		}
	}

	private void init() {

		setResizable(false);
		setIconImage(Toolkit.getDefaultToolkit().getImage(
				FormPrincipal.class.getClassLoader().getResource(
						"logo_20x20.png")));
		setTitle(ConstantsString.TITULO);
		setSize(ancho, alto);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		getContentPane().setLayout(
				new FormLayout(new ColumnSpec[] { ColumnSpec
						.decode("990px:grow"), }, new RowSpec[] {
						new RowSpec(RowSpec.CENTER, Sizes.bounded(
								Sizes.PREFERRED, Sizes.constant("28px", false),
								Sizes.constant("28px", false)), 0),
						RowSpec.decode("max(17dlu;default)"),
						new RowSpec(RowSpec.CENTER, Sizes.bounded(
								Sizes.PREFERRED,
								Sizes.constant("200px", false),
								Sizes.constant("200px", false)), 0),
						new RowSpec(RowSpec.CENTER, Sizes.bounded(
								Sizes.PREFERRED, Sizes.constant("26px", false),
								Sizes.constant("26px", false)), 0),
						new RowSpec(RowSpec.FILL, Sizes.bounded(
								Sizes.PREFERRED,
								Sizes.constant("320px", false),
								Sizes.constant("320px", false)), 0), }));

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				Controlador.desconecta();
				Controlador.salir(0);
			}
		});

		// Barra de botones
		toolBar.setFloatable(false);
		toolBar.setFocusTraversalPolicy(new FocusTraversalOnArray(
				new Component[] { btnVer, btnNuevo, btnEditar, btnEliminar,
						btnConsultar, btnAyuda }));
		getContentPane().add(toolBar, "1, 1, fill, top");

		btnVer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnVer.setToolTipText("Permite consultar los datos del cliente seleccionado en la tabla.");
		btnVer.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ver_20x20.png")));
		btnVer.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				btnVerActionPerformed();
			}
		});
		toolBar.add(btnVer);

		JSeparator separator = new JSeparator();
		separator.setMinimumSize(new Dimension(5, 28));
		separator.setMaximumSize(new Dimension(5, 28));
		separator.setPreferredSize(new Dimension(5, 28));
		toolBar.add(separator);

		btnNuevo.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnNuevo.setToolTipText("Permite registrar un nuevo cliente en la base de datos.");
		btnNuevo.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_anadir_20x20.png")));
		btnNuevo.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				btnNuevoActionPerformed();
			}
		});
		toolBar.add(btnNuevo);

		JSeparator separator_1 = new JSeparator();
		separator_1.setPreferredSize(new Dimension(5, 28));
		separator_1.setMinimumSize(new Dimension(5, 28));
		separator_1.setMaximumSize(new Dimension(5, 28));
		toolBar.add(separator_1);

		btnEditar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnEditar
				.setToolTipText("Permite editar datos del cliente seleccionado en la tabla.");
		btnEditar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_editar_20x20.png")));
		btnEditar.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				btnEditarActionPerformed();
			}
		});
		toolBar.add(btnEditar);

		JSeparator separator_2 = new JSeparator();
		separator_2.setPreferredSize(new Dimension(5, 28));
		separator_2.setMinimumSize(new Dimension(5, 28));
		separator_2.setMaximumSize(new Dimension(5, 28));
		toolBar.add(separator_2);

		btnEliminar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnEliminar
				.setToolTipText("Permite eliminar un cliente registrado en la base de datos.");
		btnEliminar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_eliminar_20x20.png")));
		btnEliminar.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				btnEliminarActionPerformed();
			}
		});
		toolBar.add(btnEliminar);

		JSeparator separator_3 = new JSeparator();
		separator_3.setPreferredSize(new Dimension(5, 28));
		separator_3.setMinimumSize(new Dimension(5, 28));
		separator_3.setMaximumSize(new Dimension(5, 28));
		toolBar.add(separator_3);

		btnConsultar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnConsultar
				.setToolTipText("<html>Ejecuta una consulta sobre las previsiones m\u00e9dicas"
						+ "<br/>para el cliente seleccionado en la tabla.</html>");
		btnConsultar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_consultar_20x20.png")));
		btnConsultar.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				try {
					btnConsultarActionPerformed();
				} catch (ExcepcionTransaccion e1) {
					ventanaInfo(ConstantsString.ERROR_CONSULTAR,
							ConstantsString.TITULO_ERROR);
					System.err.println("ERROR AL CONSULTAR");
					e1.printStackTrace();
				}
			}
		});
		toolBar.add(btnConsultar);

		JSeparator separator_4 = new JSeparator();
		separator_4.setPreferredSize(new Dimension(5, 28));
		separator_4.setMinimumSize(new Dimension(5, 28));
		separator_4.setMaximumSize(new Dimension(5, 28));
		toolBar.add(separator_4);

		btnAyuda.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnAyuda.setToolTipText("Ayuda");
		btnAyuda.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ayuda_20x20.png")));
		btnAyuda.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				btnAyudaActionPerformed(e);
			}
		});

		JMenuItem mntmPdf = new JMenuItem("Ayuda en formato pdf...");
		mntmPdf.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ayuda_16x16.png")));
		mntmPdf.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmPdfActionPerformed(e);
			}
		});
		popupAyuda.add(mntmPdf);

		JMenuItem mntmHtml = new JMenuItem("Ayuda en formato html...");
		mntmHtml.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ayuda_16x16.png")));
		mntmHtml.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmHtmlActionPerformed(e);
			}
		});
		popupAyuda.add(mntmHtml);

		toolBar.add(btnAyuda);

		JSeparator separator_5 = new JSeparator();
		separator_5.setSize(new Dimension(0, 10));
		separator_5.setPreferredSize(new Dimension(0, 10));
		separator_5.setMinimumSize(new Dimension(0, 10));
		separator_5.setMaximumSize(new Dimension(0, 10));
		getContentPane().add(separator_5, "1, 2");

		// Panel Central
		panelCentral.setFocusable(false);
		panelCentral.setLayout(new FormLayout(new ColumnSpec[] {
				new ColumnSpec(ColumnSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("200px", true),
						Sizes.constant("200px", true)), 0),
				new ColumnSpec(ColumnSpec.CENTER, Sizes.bounded(
						Sizes.PREFERRED, Sizes.constant("495px", true),
						Sizes.constant("495px", true)), 0),
				new ColumnSpec(ColumnSpec.CENTER, Sizes.bounded(
						Sizes.PREFERRED, Sizes.constant("295px", true),
						Sizes.constant("295px", true)), 0), },
				new RowSpec[] { new RowSpec(RowSpec.CENTER, Sizes.bounded(
						Sizes.PREFERRED, Sizes.constant("200px", false),
						Sizes.constant("200px", false)), 0), }));
		getContentPane().add(panelCentral, "1, 3, fill, fill");

		JLabel lblLogo = new JLabel();
		lblLogo.setFocusable(false);
		lblLogo.setMinimumSize(new Dimension(110, 110));
		lblLogo.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("logo_200x200.png")));
		lblLogo.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		lblLogo.setToolTipText("Acerca de...");
		lblLogo.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				lblLogoActionPerformed(e);
			}
		});
		panelCentral.add(lblLogo, "1, 1, center, center");

		JPanel panelBuscar = new JPanel();
		panelCentral.add(panelBuscar, "2, 1, fill, fill");
		panelBuscar.setLayout(new FormLayout(new ColumnSpec[] {
				new ColumnSpec(ColumnSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("200px", true),
						Sizes.constant("200px", true)), 0),
				new ColumnSpec(ColumnSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("300px", true),
						Sizes.constant("300px", true)), 0), }, new RowSpec[] {
				new RowSpec(RowSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("40px", false),
						Sizes.constant("40px", false)), 0),
				new RowSpec(RowSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("40px", false),
						Sizes.constant("40px", false)), 0),
				new RowSpec(RowSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("40px", false),
						Sizes.constant("40px", false)), 0),
				new RowSpec(RowSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("40px", false),
						Sizes.constant("40px", false)), 0),
				new RowSpec(RowSpec.FILL, Sizes.bounded(Sizes.PREFERRED,
						Sizes.constant("40px", false),
						Sizes.constant("40px", false)), 0), }));

		JLabel lblModo = new JLabel("Modo de b\u00fasqueda");
		lblModo.setFocusable(false);
		lblModo.setHorizontalAlignment(SwingConstants.CENTER);
		panelBuscar.add(lblModo, "1, 1, center, center");

		JPanel panelModo = new JPanel();
		panelBuscar.add(panelModo, "2, 1, fill, fill");

		ButtonGroup grupo = new ButtonGroup();

		rdbtnY.setSelected(true);
		rdbtnY.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		rdbtnY.setAlignmentX(Component.CENTER_ALIGNMENT);
		rdbtnY.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				modoBuscar = ModoBuscar.M_Y;
			}
		});
		grupo.add(rdbtnY);
		panelModo.add(rdbtnY);

		rdbtnO.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		rdbtnO.setAlignmentX(Component.CENTER_ALIGNMENT);
		rdbtnO.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				modoBuscar = ModoBuscar.M_O;
			}
		});
		grupo.add(rdbtnO);
		panelModo.add(rdbtnO);

		JLabel lblDni = new JLabel("DNI");
		lblDni.setFocusable(false);
		lblDni.setAlignmentX(Component.CENTER_ALIGNMENT);
		lblDni.setHorizontalTextPosition(SwingConstants.CENTER);
		lblDni.setHorizontalAlignment(SwingConstants.CENTER);
		panelBuscar.add(lblDni, "1, 2, center, center");

		textFieldDni = new JTextFieldFoco();
		lblDni.setLabelFor(textFieldDni);
		textFieldDni.requestFocusInWindow();
		textFieldDni.setDocument(new JTextFieldDni(textFieldDni));
		textFieldDni.addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					introCampoActionPerformed();
				}
			}
		});
		panelBuscar.add(textFieldDni, "2, 2, fill, center");

		JLabel lblNombre = new JLabel("Nombre");
		lblNombre.setFocusable(false);
		lblNombre.setHorizontalAlignment(SwingConstants.CENTER);
		panelBuscar.add(lblNombre, "1, 3, center, center");

		textFieldNombre = new JTextFieldFoco();
		lblNombre.setLabelFor(textFieldNombre);
		textFieldNombre.setColumns(10);
		textFieldNombre.addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					introCampoActionPerformed();
				}
			}
		});
		panelBuscar.add(textFieldNombre, "2, 3, fill, center");

		JLabel lblApellido = new JLabel("Apellido");
		lblApellido.setFocusable(false);
		lblApellido.setHorizontalAlignment(SwingConstants.CENTER);
		panelBuscar.add(lblApellido, "1, 4, center, center");

		textFieldApellido = new JTextFieldFoco();
		lblApellido.setLabelFor(textFieldApellido);
		textFieldApellido.setColumns(10);
		textFieldApellido.addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					introCampoActionPerformed();
				}
			}
		});
		panelBuscar.add(textFieldApellido, "2, 4, fill, center");

		JLabel lblTelefono = new JLabel("Tel\u00e9fono");
		lblTelefono.setFocusable(false);
		lblTelefono.setHorizontalAlignment(SwingConstants.CENTER);
		panelBuscar.add(lblTelefono, "1, 5, center, center");

		textFieldTelefono = new JTextFieldFoco();
		lblTelefono.setLabelFor(textFieldTelefono);
		textFieldTelefono
				.setDocument(new JTextFieldLimite(textFieldTelefono, 9));
		textFieldTelefono.setColumns(10);
		textFieldTelefono.addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					introCampoActionPerformed();
				}
			}
		});
		panelBuscar.add(textFieldTelefono, "2, 5, fill, center");

		btnBuscar.setHorizontalTextPosition(SwingConstants.CENTER);
		btnBuscar.setVerticalTextPosition(SwingConstants.BOTTOM);
		btnBuscar.setPreferredSize(new Dimension(98, 54));
		btnBuscar.setMaximumSize(new Dimension(98, 54));
		btnBuscar.setMinimumSize(new Dimension(98, 54));
		btnBuscar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnBuscar
				.setToolTipText("<html>Permite buscar un cliente registrado en la base de datos"
						+ "<br/>en funci\u00f3n de los par\u00e1metros y modo seleccionados.</html>");
		btnBuscar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_buscar_20x20.png")));
		btnBuscar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnBuscarActionPerformed();
			}
		});
		panelCentral.add(btnBuscar, "3, 1, center, center");

		btnTodos.setHorizontalTextPosition(SwingConstants.CENTER);
		btnTodos.setVerticalTextPosition(SwingConstants.BOTTOM);
		btnTodos.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnTodos.setPreferredSize(new Dimension(80, 54));
		btnTodos.setMaximumSize(new Dimension(80, 54));
		btnTodos.setMinimumSize(new Dimension(80, 54));
		btnTodos.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		btnTodos.setToolTipText("Muestra todos los clientes del sistema.");
		btnTodos.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ver_20x20.png")));
		btnTodos.setEnabled(false);
		btnTodos.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				btnTodosActionPerformed();
			}
		});
		panelCentral.add(btnTodos, "3, 1, center, bottom");

		// Tabla
		tabla = new JTable() {

			private static final long serialVersionUID = 1L;

			@Override
			public Component prepareRenderer(TableCellRenderer renderer,
					int rowIndex, int vColIndex) {
				Component c = super.prepareRenderer(renderer, rowIndex,
						vColIndex);
				if (c instanceof JComponent) {
					JComponent jc = (JComponent) c;
					jc.setToolTipText((String) getValueAt(rowIndex, vColIndex));
				}
				return c;
			}
		};
		tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		tabla.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		tabla.getTableHeader().setReorderingAllowed(false);
		tabla.setAutoCreateRowSorter(false);
		tabla.setFillsViewportHeight(true);
		tabla.setModel(new DefaultTableModel(new String[][] {
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null },
				{ null, null, null, null, null, null, null, null }, },
				new String[] { "DNI", "Nombre", "Primer apellido",
						"Segundo apellido", "Tel\u00E9fono",
						"Fecha de nacimiento", "Localidad", "Provincia" }) {
			private static final long serialVersionUID = 1L;

			boolean[] columnEditable = new boolean[] { false, false, false,
					false, false, false, false, false };

			@Override
			public boolean isCellEditable(int rowIndex, int columnIndex) {
				return columnEditable[columnIndex];
			}

		});
		tabla.getColumnModel().getColumn(0).setMinWidth(75);
		tabla.getColumnModel().getColumn(0).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(1).setMinWidth(75);
		tabla.getColumnModel().getColumn(1).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(2).setMinWidth(75);
		tabla.getColumnModel().getColumn(2).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(3).setMinWidth(75);
		tabla.getColumnModel().getColumn(3).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(4).setMinWidth(75);
		tabla.getColumnModel().getColumn(4).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(5).setMinWidth(75);
		tabla.getColumnModel().getColumn(5).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(6).setMinWidth(75);
		tabla.getColumnModel().getColumn(6).setPreferredWidth(300);
		tabla.getColumnModel().getColumn(7).setMinWidth(75);
		tabla.getColumnModel().getColumn(7).setPreferredWidth(300);

		tabla.addKeyListener(new KeyAdapter() {

			public void keyPressed(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					introTablaActionPerformed(e);
				} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
					tabTablaActionPerformed(e);
				}
			}
		});

		tabla.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				int filaClick = e.getY() / tabla.getRowHeight();
				actualizaSeleccion(filaClick + 1);
				if (!e.isMetaDown()) { // Si no es el derecho
					if (e.getClickCount() == 2) {
						dobleClickTablaActionPerformed();
					}
				} else {
					botonDerechoTablaActionPerformed(e);
				}
			}
		});

		tabla.addFocusListener(new FocusAdapter() {

			public void focusGained(FocusEvent e) {
				if (tabla.getSelectedRowCount() == 0) {
					actualizaSeleccion(1);
				}
			}
		});

		JSeparator separator_6 = new JSeparator();
		separator_6.setPreferredSize(new Dimension(0, 10));
		separator_6.setMinimumSize(new Dimension(0, 10));
		separator_6.setMaximumSize(new Dimension(0, 10));
		separator_6.setSize(new Dimension(0, 10));
		getContentPane().add(separator_6, "1, 4, fill, fill");

		// Scroll tabla
		scrollPane.setViewportView(tabla);
		getContentPane().add(scrollPane, "1, 5, fill, fill");

		// Popup tabla
		JMenuItem mntmVer = new JMenuItem("Ver...");
		mntmVer.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_ver_16x16.png")));
		mntmVer.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmVerActionPerformed(e);
			}
		});
		popupMenu.add(mntmVer);

		JMenuItem mntmEditar = new JMenuItem("Editar...");
		mntmEditar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_editar_16x16.png")));
		mntmEditar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmEditarActionPerformed(e);
			}
		});
		popupMenu.add(mntmEditar);

		JMenuItem mntmConsultar = new JMenuItem("Consultar...");
		mntmConsultar.setIcon(new ImageIcon(FormPrincipal.class
				.getClassLoader().getResource("icono_consultar_16x16.png")));
		mntmConsultar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmConsultarActionPerformed(e);
			}
		});
		popupMenu.add(mntmConsultar);

		JMenuItem mntmEliminar = new JMenuItem("Eliminar");
		mntmEliminar.setIcon(new ImageIcon(FormPrincipal.class.getClassLoader()
				.getResource("icono_eliminar_16x16.png")));
		mntmEliminar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				mntmEliminarActionPerformed(e);
			}
		});
		popupMenu.add(mntmEliminar);

		setFocusTraversalPolicy(new FocusTraversalOnArray(new Component[] {
				textFieldDni, textFieldNombre, textFieldApellido,
				textFieldTelefono, btnBuscar, tabla, toolBar, rdbtnY, rdbtnO }));

	}

	private void introCampoActionPerformed() {
		buscar();
	}

	private void introTablaActionPerformed(KeyEvent e) {
		ver();
	}

	private void lblLogoActionPerformed(MouseEvent e) {
		if (!e.isMetaDown()) {
			ventanaInfo(ConstantsString.ACERCA_DE,
					ConstantsString.TITULO_ACERCA_DE);
		}
	}

	private void mntmConsultarActionPerformed(ActionEvent e) {
		consultar();
	}

	private void mntmEditarActionPerformed(ActionEvent e) {
		editar();
	}

	private void mntmEliminarActionPerformed(ActionEvent e) {
		eliminar();
	}

	private void mntmHtmlActionPerformed(ActionEvent e) {
		Controlador.ayuda(false);
	}

	private void mntmPdfActionPerformed(ActionEvent e) {
		Controlador.ayuda(true);
	}

	private void mntmVerActionPerformed(ActionEvent e) {
		ver();
	}

	private boolean seleccionaCliente() {
		if (tabla.getSelectedRow() != -1) {
			String dni = (String) tabla.getValueAt(tabla.getSelectedRow(), 0);
			if (dni != null) {
				Controlador.dni = dni;
				return true;
			}
		}
		ventanaInfo(ConstantsString.ERROR_CLIENTE_TABLA,
				ConstantsString.TITULO_INFO);
		return false;
	}

	private void tabTablaActionPerformed(KeyEvent e) {
		if (e.getModifiers() == KeyEvent.SHIFT_MASK) {
			btnBuscar.requestFocusInWindow();
		} else {
			btnVer.requestFocusInWindow();
		}
		int fila = tabla.getSelectedRow();
		if (fila < 2) {
			actualizaSeleccion(1);
		} else {
			actualizaSeleccion(fila);
		}
	}

	private void ver() {
		if (seleccionaCliente()) {
			Controlador.showVistaSecundaria(ModoFormSecundario.M_VER);
		}
	}

}
